﻿using System;
using System.Globalization;
using System.IO;
using System.Xml.Serialization;
using System.Collections;

namespace SharePoint.ImportExport.Core 
{
	/// <summary>
	/// This is the enumeration of datacontainer types
	/// </summary>
	/// <remarks>
	/// Valid choices are Library or folder</remarks>
	public enum DataContainerType
	{
		/// <summary>
		/// Default value used only to ensure that the correct value is set
		/// </summary>
		Undefined,
		/// <summary>
		/// Type library
		/// </summary>
		Library,
		/// <summary>
		/// Type folder is only allowed for document libraries
		/// </summary>
		Folder
	}
	/// <summary>
	/// This is the enumeration of site types
	/// </summary>
	public enum SiteType
	{
		/// <summary>
		/// Default value used only to ensure that the correct value is set
		/// </summary>
		Undefined,
		/// <summary>
		/// WSS Site
		/// </summary>
		Site,
		/// <summary>
		/// Portal Area
		/// </summary>
		Area
	}
	/// <summary>
	/// This is the enum that controls the site/list/library creation
	/// </summary>
	public enum Verbs
	{
		/// <summary>
		/// The container will be created(fails if it already exists) 
		/// </summary>
		create,
		/// <summary>
		/// The container will be modified. The settings will be changed and items appended unless they are created/modified on the same date by the same author/editor 
		/// </summary>
		modify,
		/// <summary>
		/// The container will be deleted
		/// </summary>
		delete,
		/// <summary>
		/// The container will be emptied
		/// </summary>
		clear
	}
	/// <summary>
	/// This is the enumeration of the AlertTypes
	/// </summary>

	public enum AlertType
	{
		/// <summary>
		/// Add
		/// </summary>
		Add,
		/// <summary>
		/// All
		/// </summary>
		All,
		/// <summary>
		/// Delete
		/// </summary>
		Delete,
		/// <summary>
		/// Discussion
		/// </summary>
		Discussion,
		/// <summary>
		/// Modify
		/// </summary>
		Modify

	}
	
#if(DEBUG)
	/// <summary>
	/// This class is designed to facilitate the creation of the datafiles needed by the SharePoint Importer
	/// A good starting point is <see cref="SharePoint.ImportExport.Core.Import"/>
	/// <example>
	/// <code>
	/// //Create a new instance of the Import class
	/// SharePointExtractor.Import import = new Import();
	/// import.Settings.Locale="1033"; //US english
	/// 		
	/// RootContainer rootContainer= new RootContainer();
	/// rootContainer.Type=SiteType.Site; //WSS site, SiteType.Area=Portal area
	/// rootContainer.Name=""; //Create the sites in the root of the WSS server 
	/// 
	/// //This class is the actual site that will be created
	/// SharePointExtractor.Container container= new Container();
	/// rootContainer.Containers.Add(container);
	/// import.RootContainers.Add(rootContainer);
	/// 
	/// container.Name="Test";
	/// container.Owner="DOMAIN\\user";
	/// container.Contact="user@domain.com";
	/// container.Type=SiteType.Site;
	/// container.Template="STS#1"; //Empty WSS Team site
	/// 
	/// //Add an contributor
	/// User user= new User();
	/// user.Account="DOMAIN\\User2";
	/// user.Role="contributor";
	/// user.Email="user2@domain.com";
	/// user.Name="Joe User";
	/// user.Type="Person";
	/// container.Security.Users.Add(user);
	/// 
	/// //Create a document library
	/// SharePointExtractor.DataContainer dataContainer=new DataContainer();
	/// dataContainer.Name="My Document Library";
	/// dataContainer.Type=DataContainerType.Library;
	/// 
	/// // Use then custom List Template
	/// dataContainer.Template="My Library";
	/// // That is based on the documentlibrary template
	/// dataContainer.BaseTemplate="DocumentLibrary";
	/// dataContainer.WebPart=true;
	/// dataContainer.QuickLaunch=true;	
	/// dataContainer.RelativeitemXML="\\items.xml"; //This is the path to the file with the items
	/// container.DataContainers.Add(dataContainer);
	/// //Create a new list object that will contain the actual items
	/// List list = new List();
	/// Profile profile = new Profile();
	/// profile.Name=dataContainer.Template;
	/// list.Profiles.Add(profile);
	/// try
	///		{
	///			list.Serialize("items.xml");
	///		}
	///	catch(SPExportException ex)
	///		{
	///			Console.WriteLine("Exception occurred: "+ex.Message);
	///		}
	/// 
	/// //Validate the schema prior to saving
	/// if(!import.Validate())
	///		Console.WriteLine("Validation failed, last error: "+import.LastError);
	///	else
	///		{
	///		
	///			try
	///				{
	///					import.Serialize("struct.xml");
	///				}
	///			catch(SPExportException ex)
	///				{
	///					Console.WriteLine("Exception occurred: "+ex.Message);
	///				}
	///		}
	///		
	/// </code>
	/// </example>
	/// </summary>
	
	public class NamespaceDoc
	{
	}
#endif
		/// <summary>
		/// This is the main class for creating the exported data. 
		/// </summary>
		/// <remarks>There has to be exactly one instance of this class for each struct.xml file. <seealso cref="SharePoint.ImportExport.Core.RootContainer"/><seealso cref="SharePoint.ImportExport.Core.DataContainer"/><seealso cref="SharePoint.ImportExport.Core.Container"/></remarks>
		/// <example>
		/// <code>
		/// //Create a new instance of the Import class
		/// SharePoint.ImportExport.Core.Import import = new Import();
		/// import.Settings.Locale="1033"; //US english
		/// 		
		/// RootContainer rootContainer= new RootContainer();
		/// rootContainer.Type=SiteType.Site; //WSS site, SiteType.Area=Portal area
		/// rootContainer.Name=""; //Create the sites in the root of the WSS server 
		/// 
		/// //This class is the actual site that will be created
		/// SharePoint.ImportExport.Core.Container container= new Container();
		/// rootContainer.Containers.Add(container);
		/// import.RootContainers.Add(rootContainer);
		/// 
		/// container.Name="Test";
		/// container.Owner="DOMAIN\\user";
		/// container.Contact="user@domain.com";
		/// container.Type=SiteType.Site;
		/// container.Template="STS#1"; //Empty WSS Team site
		/// 
		/// //Add an contributor
		/// User user= new User();
		/// user.Account="DOMAIN\\User2";
		/// user.Role="contributor";
		/// user.Email="user2@domain.com";
		/// user.Name="Joe User";
		/// user.Type="Person";
		/// container.Security.Users.Add(user);
		/// 
		/// //Create a document library
		/// SharePoint.ImportExport.Core.DataContainer dataContainer=new DataContainer();
		/// dataContainer.Name="My Document Library";
		/// dataContainer.Type=DataContainerType.Library;
		/// 
		/// // Use then custom List Template
		/// dataContainer.Template="My Library";
		/// // That is based on the documentlibrary template
		/// dataContainer.BaseTemplate="DocumentLibrary";
		/// dataContainer.WebPart=true;
		/// dataContainer.QuickLaunch=true;	
		/// dataContainer.RelativeitemXML="\\items.xml"; //This is the path to the file with the items
		/// container.DataContainers.Add(dataContainer);
		/// //Create a new list object that will contain the actual items
		/// List list = new List();
		/// Profile profile = new Profile();
		/// profile.Name=dataContainer.Template;
		/// list.Profiles.Add(profile);
		/// try
		///		{
		///			list.Serialize("items.xml");
		///		}
		///	catch(SPExportException ex)
		///		{
		///			Console.WriteLine("Exception occurred: "+ex.Message);
		///		}
		/// 
		/// //Validate the schema prior to saving
		/// if(!import.Validate())
		///		Console.WriteLine("Validation failed, last error: "+import.LastError);
		///	else
		///		{
		///		
		///			try
		///				{
		///					import.Serialize("struct.xml");
		///				}
		///			catch(SPExportException ex)
		///				{
		///					Console.WriteLine("Exception occurred: "+ex.Message);
		///				}
		///		}
		///		
		/// </code>
		/// </example>
		

		[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
			public class Import 
		{
        
				
			private Settings settings;
			
			/// <summary>
			/// This is the settings section
			/// </summary>
			/// <remarks>This is used to specify the locale information for the exported data. the importer uses this information in order to parse the dates etc in the right format</remarks>
			[System.Xml.Serialization.XmlElementAttribute("settings",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public Settings Settings
			{
				get
				{
					return settings;
				}
				set
				{
					settings=value;
				}
			}
        
			private RootContainersCollection rootContainers;
			/// <summary>
			/// This is an array of rootcontainer nodes. The rootcontainer defines the starting point of the import
			/// </summary>
			/// <remarks>Usually the struct.xml file contains just one rootcontainer node</remarks>
			[System.Xml.Serialization.XmlElementAttribute("rootcontainer",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public RootContainersCollection RootContainers
			{
				get
				{
					return rootContainers;
				}
			}


			private void ValidateDataContainer(DataContainer dataContainer)
			{
				if(dataContainer==null)
					return;
				if(dataContainer.Type==DataContainerType.Undefined)
				{
					throw new SPExportException("A DataContainer must have its type defined");
				}
				if(dataContainer.Name==null)
				{
					throw new SPExportException("A DataContainer must have a name defined");
				}
				if(DataContainerType.Library!=dataContainer.Type && DataContainerType.Folder!=dataContainer.Type)
					throw new SPExportException("A data container must either be of type  \"Library\" or \"Folder\"");
				if(dataContainer.Template==null && dataContainer.BaseTemplate==null )
				{
					if(dataContainer.Type!=DataContainerType.Folder)
						throw new SPExportException("A DataContainer must have either a template or a base template defined");
				}

				if(dataContainer.Type==DataContainerType.Folder)
				{
					if(dataContainer.BaseTemplate != null)
					{
						//Check that the parent folder is of type library
						if(dataContainer.BaseTemplate.IndexOf("Library")>-1 || dataContainer.BaseTemplate.IndexOf("XMLForm")>-1  || dataContainer.BaseTemplate.IndexOf("Catalog")>-1 || dataContainer.BaseTemplate.Length==3 || dataContainer.BaseTemplate.IndexOf("DataSources")>-1)
						{
							if(dataContainer.DataContainers != null)
							{
								foreach(DataContainer childDataContainer in dataContainer.DataContainers)
								{
									try
									{
										ValidateDataContainer(childDataContainer );
									}
									catch(SPExportException ex)
									{
										throw ex;

									}
								}
							}
						}
						else
						{
							if(dataContainer.DataContainers!=null && dataContainer.DataContainers.Count!=0)
							{
								throw(new SPExportException("Error validating :"+dataContainer.Name+". DataContainers are only allowed for libraries."));
							}
						}
					}
				}
				else
				{
					if(dataContainer.DataContainers != null)
					{
						foreach(DataContainer childDataContainer in dataContainer.DataContainers)
						{
							if(childDataContainer.Type!=DataContainerType.Folder)
							{
								throw(new SPExportException("Child DataContainers must be of type Folder"));
							}
							else
							{
								try
								{
									ValidateDataContainer(childDataContainer );
								}
								catch(SPExportException ex)
								{
									throw ex;

								}
							}
						}
					}

				}
			}
			private void ValidateContainer(Container container)
			{
				if(container.Name==null)
					throw new SPExportException("A Container must have a name defined");
				if(container.Owner==null)
					throw new SPExportException("A Container must have an owner defined");
				if(container.Contact==null)
					throw new SPExportException("A Container must have a contact defined");
				if(container.Type==SiteType.Undefined)
					throw (new SPExportException("The container: "+container.Name+" must either be of type \"site\" or \"area\""));
				if(container.Type==SiteType.Site || container.Type==SiteType.Area)
				{
					if(container.DataContainers!= null)
					{
						foreach(DataContainer dataContainer in container.DataContainers)
						{
							if(dataContainer != null)
							{
								try
								{
									ValidateDataContainer(dataContainer);
								}
								catch(SPExportException ex)
								{
									throw new SPExportException("Datacontainer validation in container "+container.Name + " failed. Error: "+ex.Message);
								}
							}
						}
					}
					if(container.Containers!= null)
					{
						foreach(Container childContainer in container.Containers)
						{
							if(childContainer != null)
							{
								try
								{
									ValidateContainer(childContainer);
								}
								catch(SPExportException ex)
								{
									throw new SPExportException("Container validation in container "+container.Name + "failed. Error: "+ex.Message);
								}
							}
						}
					}
					if(container.Security != null)
					{
						foreach(User user in container.Security.Users)
						{
							if(user.Account==null)
								throw new SPExportException("The user defined in container "+container.Name+" must have an account defined");
							if(user.Role==null)
								throw new SPExportException("The user defined in container "+container.Name+" must have a role defined");
						}
					}
				}
				else
				{
					throw (new SPExportException("The container: "+container.Name+" must either be of type \"site\" or \"area\""));
				}
			}
			/// <summary>
			/// This is the serialization function for the import class
			/// </summary>
			/// <param name="fileName">this is the name of the XML file that will be generated</param>
			/// <returns></returns>
			/// <remarks>The method will throw as SPExportException if the data is invalid</remarks>
			public bool Serialize(string fileName)
			{
				string dirName=fileName;
				int pos=dirName.LastIndexOf("\\");
				if(pos>0)
					dirName=dirName.Substring(0,pos);
					
				if(pos!=-1) //Create the file in the working directory
				{
					if (!Directory.Exists(dirName))
						Directory.CreateDirectory(dirName);
				}

				if(!Validate())
				{
					throw new SPExportException(LastError);
				}


				StreamWriter exportFile = new StreamWriter(fileName,false);
				try
				{
					XmlSerializer mySerializer = new XmlSerializer(typeof(Import));
					mySerializer.Serialize(exportFile, this);
				}
				catch(IOException exSerialize)
				{
					Console.WriteLine("Exception error: "+exSerialize.Message);
					SPExportException ex= new SPExportException(exSerialize.Message);
					throw ex;
				}
				finally
				{
					exportFile.Flush();
					exportFile.Close();
					
				}
				return true;


			}
			/// <summary>
			/// This is the default constructor for the class
			/// </summary>
			public Import()
			{
				rootContainers= new  RootContainersCollection();
				settings=new Settings();
			}
			/// <summary>
			/// This is the constructor with the lcid parameter for the class
			/// </summary>
			public Import(string lcid)
			{
				rootContainers= new  RootContainersCollection();
				settings=new Settings();
				settings.Locale=lcid;
			}
			/// <summary>
			/// This is the constructor with the lcid parameter for the class
			/// </summary>
			public Import(string lcid, SiteType rootContainerType, string rootContainerName)
			{
				rootContainers= new  RootContainersCollection();
				settings=new Settings();
				settings.Locale=lcid;
				RootContainer rootContainer=new RootContainer();
				rootContainer.Type=rootContainerType;
				rootContainer.Name=rootContainerName;
				RootContainers.Add(rootContainer);

			}

			/// <summary>
			/// This is the last error from the validation
			/// </summary>
			private string lastError="";

			/// <summary>
			/// This is the last error from the validation
			/// </summary>
			public string LastError
			{
				get
				{
					return lastError;
				}
			}

			/// <summary>
			/// This function validates the class
			/// </summary>
			public bool Validate()
			{
				bool returnValue=true;
				if(Settings==null)
				{
					lastError="The settings must be defined";
					return false;
				}
				else
				{
					if(Settings.Locale.Length==0)
						Settings.Locale=System.Threading.Thread.CurrentThread.CurrentUICulture.LCID.ToString(CultureInfo.
							InvariantCulture);

				}
				if(RootContainers==null)
				{
					lastError="At least one rootcontainer must be defined";
					return false;
				}
				else
				{
					//Start validation 
					foreach(RootContainer rootContainer in RootContainers)
					{
						if(rootContainer.Type==SiteType.Undefined)
						{
							lastError="The rootcontainer: "+rootContainer.Name+" must either be of type \"site\" or \"area\"";
							return false;
						}
						if(rootContainer.Type==SiteType.Site|| rootContainer.Type==SiteType.Area)
						{
							if(rootContainer.Containers==null)
							{
								lastError="At least one container must be defined in rootcontainer: "+rootContainer.Name;
								return false;
							}
							else
							{
								foreach(Container container in rootContainer.Containers)
								{
									try
									{
										ValidateContainer(container);
									}
									catch(SPExportException ex)
									{
										lastError=ex.Message;
										returnValue=false;
									}
								}
							}
						}
						else
						{
							lastError="The rootcontainer: "+rootContainer.Name+" must either be of type \"site\" or \"area\"";
							returnValue=false;
						}

					}
				}
				return returnValue;
			}
		}
    
		/// <summary>
		/// This is the settings class
		/// </summary>
		public class Settings 
		{
        
			/// <summary>
			/// This defines the locale that the data was extacted from
			/// </summary>
			private string locale;

			/// <summary>
			/// This defines the locale that the data was extacted from
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("locale",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string Locale
			{
				get
				{
					return locale;
				}
				set
				{
					locale=value;
				}
			}
		}
		/// <summary>
		/// This is the class implementing the Alerts collection
		/// </summary>
		public class AlertsCollection:ICollection
		{
			/// <summary>
			/// This is the default constructor for the AlertsCollection class
			/// </summary>
			/// <remarks>Instantiates the alerts member</remarks>
			public AlertsCollection()
			{
				alerts=new ArrayList();
			}
			private ArrayList alerts;
			#region ICollection Members

			/// <summary>
			/// Gets a value indicating whether access to the ArrayList is synchronized (thread-safe).
			/// </summary>
			/// <remarks>
			/// To guarantee the thread safety of the ArrayList, all operations must be done through the wrapper returned by the Synchronized method.
			/// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads.
			/// </remarks>
			public bool IsSynchronized
			{
				get
				{
				
					return alerts.IsSynchronized;
				}
			}

			/// <summary>
			/// Returns a value indicating the number of objects in the collection. Read-only.
			/// </summary>
			public int Count
			{
				get
				{
					return alerts.Count;
				}
			}

			/// <summary>
			/// Copies the entire Alert array to a compatible one-dimensional Array, starting at the specified index of the target array.
			/// </summary>
			/// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
			/// <param name="index">The zero-based index in array at which copying begins</param>
			public void CopyTo(Alert[] a, int index)
			{
				alerts.CopyTo(a, index);
			}
			/// <summary>
			/// Copies the entire ArrayList to a compatible one-dimensional Array, starting at the specified index of the target array.
			/// </summary>
			/// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
			/// <param name="index">The zero-based index in array at which copying begins</param>
			public void CopyTo(Array a, int index)
			{
				alerts.CopyTo(a, index);
			}

			/// <summary>
			/// Gets an object that can be used to synchronize access to the ArrayList.
			/// </summary>
			/// <remarks>
			/// To create a synchronized version of the ArrayList, use the Synchronized method. However, derived classes can provide their own synchronized version of the ArrayList using the SyncRoot property. The synchronizing code must perform operations on the SyncRoot of the ArrayList, not directly on the ArrayList. This ensures proper operation of collections that are derived from other objects. 
			/// Specifically, it maintains proper synchronization with other threads that might be simultaneously modifying the ArrayList object.
			/// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or 
			/// catch the exceptions resulting from changes made by other threads.
			/// </remarks>
			public object SyncRoot
			{
				get
				{
					return alerts.SyncRoot;
				}
			}

			#endregion

			#region IEnumerable Members

			/// <summary>
			/// Returns an enumerator that can iterate through the ArrayList.
			/// </summary>
			/// <returns></returns>
			public IEnumerator GetEnumerator()
			{
				return alerts.GetEnumerator() ;
			}

			#endregion
			/// <summary>
			/// Gets the element at the specified index.
			/// </summary>
			public Alert this[int index]
			{
				get{return (Alert) alerts[index];}
			}
			/// <summary>
			/// Adds an object to the end of the ArrayList.
			/// </summary>
			/// <param name="newAlert">New Alert to be added to the list</param>

			public void Add(Alert  newAlert)
			{
				alerts.Add(newAlert);
			}

		}
    
		/// <summary>
		/// This is the class that encapsulates a WSS alert
		/// </summary>
		/// <example>
		/// <code>
		/// //Create a new alert
		/// Alert alert= new Alert();
		/// alert.Frequency="Daily";
		/// alert.User="DOMAIN\\user";
		/// alert.Type="Modify";
		/// dataContainer.Alerts.Alert.Add(alert);
		/// </code>
		/// </example>
		/// <remarks>
		/// Valid choices for Alert.Type are
		/// <list type="bullet">
		/// <item>Add</item>
		/// <item>All</item>
		/// <item>Delete</item>
		/// <item>Discussion</item>
		/// <item>Modify</item>
		/// </list>
		/// </remarks>

		public class Alert 
		{
			/// <summary>
			/// This is the user that will receive the alert, format either DOMAIN\user or user@domain.com
			/// </summary>
			private string user;
			/// <summary>
			/// This is the user that the alert belongs to
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("user",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string User
			{
				get
				{
					return user;
				}
				set
				{
					user=value;
				}
			}
        
			/// <summary>
			/// This is the type of the alert
			/// </summary>
			/// <remarks>
			/// Valid choices are
			/// <list type="bullet">
			/// <item>Add</item>
			/// <item>All</item>
			/// <item>Delete</item>
			/// <item>Discussion</item>
			/// <item>Modify</item>
			/// </list>
			/// </remarks>
			private AlertType type;
			/// <summary>
			/// This is the type of the alert
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("type",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public AlertType Type
			{
				get
				{
					return type;
				}
				set
				{
					type=value;
				}
			}

			/// <summary>
			/// This is the frequency for the alert
			/// </summary>
			/// <remarks>
			/// Valid types are
			/// <list type="bullet">
			/// <item>Daily</item>
			/// <item>Immediate</item>
			/// <item>Weekly</item>
			/// </list>
			/// </remarks>
			private string frequency;

			/// <summary>
			/// This is the frequency of the alert
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("frequency",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string Frequency
			{
				get
				{
					return frequency;
				}
				set
				{
					frequency=value;
				}
			}

		}
    
		/// <summary>
		/// This is a list of the alerts specified for the list or listitem
		/// </summary>
		/// <remarks>
		/// This class is used to create the WSS alerts</remarks>
		/// <example>
		/// <code>
		/// //Create a new alert
		/// Alert alert= new Alert();
		/// alert.Frequency="Daily";
		/// alert.User="DOMAIN\\user";
		/// alert.Type="Modify";
		/// dataContainer.Alerts.Alert.Add(alert);
		/// </code>
		/// </example>
		public class Alerts 
		{
        
			/// <summary>
			/// List of alerts
			/// </summary>
				
			private AlertsCollection alert;
			/// <summary>
			/// This is the list of alerts
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("alert",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public AlertsCollection Alert
			{
				get
				{
					return alert;
				}
			}

			/// <summary>
			/// This is the default constructor for the Alerts class
			/// </summary>
			/// <remarks>Instantiates the Alert member</remarks>
			public Alerts()
			{
				alert= new AlertsCollection();
			}
		}
    
		/// <summary>
		/// This is the class implementing the DataCotainers collection
		/// </summary>
		public class DataContainersCollection:ICollection
		{
			/// <summary>
			/// This is the default constructor for the DataContainersCollection class
			/// </summary>
			/// <remarks>Instantiates the dataContainers member</remarks>
			public DataContainersCollection()
			{
				dataContainers=new ArrayList();
			}
			private ArrayList dataContainers;
			#region ICollection Members
			/// <summary>
			/// Gets a value indicating whether access to the ArrayList is synchronized (thread-safe).
			/// </summary>
			/// <remarks>
			/// To guarantee the thread safety of the ArrayList, all operations must be done through the wrapper returned by the Synchronized method.
			/// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads.
			/// </remarks>
			public bool IsSynchronized
			{
				get
				{
				
					return dataContainers.IsSynchronized;
				}
			}

			/// <summary>
			/// Returns a value indicating the number of objects in the collection. Read-only.
			/// </summary>
			public int Count
			{
				get
				{
					return dataContainers.Count;
				}
			}

			/// <summary>
			/// Copies the entire ArrayList to a compatible one-dimensional Array, starting at the specified index of the target array.
			/// </summary>
			/// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
			/// <param name="index">The zero-based index in array at which copying begins</param>
			public void CopyTo(DataContainer[]a, int index)
			{
				dataContainers.CopyTo(a, index);
			}
			/// <summary>
			/// Copies the entire ArrayList to a compatible one-dimensional Array, starting at the specified index of the target array.
			/// </summary>
			/// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
			/// <param name="index">The zero-based index in array at which copying begins</param>
			public void CopyTo(Array a, int index)
			{
				dataContainers.CopyTo(a, index);
			}

			/// <summary>
			/// Gets an object that can be used to synchronize access to the ArrayList.
			/// </summary>
			/// <remarks>
			/// To create a synchronized version of the ArrayList, use the Synchronized method. However, derived classes can provide their own synchronized version of the ArrayList using the SyncRoot property. The synchronizing code must perform operations on the SyncRoot of the ArrayList, not directly on the ArrayList. This ensures proper operation of collections that are derived from other objects. 
			/// Specifically, it maintains proper synchronization with other threads that might be simultaneously modifying the ArrayList object.
			/// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or 
			/// catch the exceptions resulting from changes made by other threads.
			/// </remarks>
			public object SyncRoot
			{
				get
				{
					return dataContainers.SyncRoot;
				}
			}

			#endregion

			#region IEnumerable Members

			/// <summary>
			/// Returns an enumerator that can iterate through the ArrayList.
			/// </summary>
			/// <returns></returns>
			public IEnumerator GetEnumerator()
			{
				return dataContainers.GetEnumerator() ;
			}

			#endregion
			/// <summary>
			/// Gets the element at the specified index.
			/// </summary>
			public DataContainer this[int index]
			{
				get{return (DataContainer) dataContainers[index];}
			}
			/// <summary>
			/// Adds an object to the end of the ArrayList.
			/// </summary>
			/// <param name="newDataContainer">New DataContainer to be added to the list</param>
			public void Add(DataContainer  newDataContainer)
			{
				dataContainers.Add(newDataContainer);
			}
			/// <summary>
			/// This method removes a named item from the collection
			/// </summary>
			/// <param name="Name">This is the name of the node to be removed</param>
			public bool Remove(string Name)
			{
				int indexToRemove=-1;
				for(int i = 0 ; i<dataContainers.Count;i++)
				{
					DataContainer dc=(DataContainer)dataContainers[i];
					if(0==dc.Name.CompareTo(Name))
					{
						indexToRemove=i;
						break;
					}

				}
				if(indexToRemove>=0)
					dataContainers.RemoveAt(indexToRemove);
				return (indexToRemove>=0);
			}

		}

		/// <summary>
		/// This is the class that encapsulates the list or library
		/// </summary>
		/// <remarks><seealso cref="SharePoint.ImportExport.Core.Profile"/></remarks>
		/// <example>
		/// <code>
		/// //Create a document library
		/// SharePoint.ImportExport.Core.DataContainer datacontainer=new DataContainer();
		/// datacontainer.Name="My Document Library";
		/// datacontainer.Type=DataContainerType.Library;
		/// datacontainer.Template="My Document Library";// Use then custom List Template
		/// datacontainer.BaseTemplate="DocumentLibrary";
		/// datacontainer.WebPart=true;
		/// datacontainer.QuickLaunch=true;    
		/// datacontainer.RelativeitemXML="\\items.xml"; //This is the path to the file with the items
		/// container.DataContainers.Add(datacontainer);
		/// //Create a new list object that will contain the actual items
		/// List list = new List();
		/// Profile profile = new Profile();
		/// profile.Name=datacontainer.Template;
		/// list.Profiles.Add(profile);
		/// try
		///		{
		///			list.Serialize("items.xml");
		///		}
		///	catch(SPExportException ex)
		///		{
		///			Console.WriteLine("Exception occurred: "+ex.Message);
		///		}
		/// 
		/// 
		/// DataContainer listContainer = new DataContainer();
		/// listContainer.Template = "Links"; //Use standard links list
		/// listContainer.Name = "Created Subsites";
		/// listContainer.WebPart = true;
		/// listContainer.InheritPermissions = true;
		/// listContainer.RelativeitemXML = relativePath+"ListItems.xml";
		/// listContainer.Type = DataContainerType.Library;
		/// container.DataContainers.Add(listContainer);
		/// </code></example>
		public class DataContainer 
		{
        
			/// <summary>
			/// This is the type of the list/library.
			/// </summary>
			/// <remarks>In most cases this is "Library" but for sub folders in a document library it is "Folder"<seealso cref="SharePoint.ImportExport.Core.DataContainersCollection"></seealso> and <seealso cref="SharePoint.ImportExport.Core.Container"/>"/></remarks>
			private DataContainerType type=DataContainerType.Undefined;
			/// <summary>
			/// This is the type of the datacontainer
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("type",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public DataContainerType Type
			{
				get
				{
					return type;
				}
				set
				{
					type=value;
				}
			}
    
			/// <summary>
			/// This is the name of the list/library
			/// </summary>
			private string name;
			/// <summary>
			/// This is the name of the data container
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("name",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string Name
			{
				get
				{
					return name;
				}
				set
				{
					name=Miscallaneous.FixName(value);
				}
			}
        
			/// <summary>
			/// This is the template the list/library is based on
			/// </summary>
			private string template;
			/// <summary>
			/// This is the template the list/library is based on
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("template",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string Template
			{
				get
				{
					return template;
				}
				set
				{
					template=value;
				}
			}

        
			/// <summary>
			/// This is the base template that the custom list is based on (optional)
			/// </summary>
			private string baseTemplate;
			/// <summary>
			/// This is the template the custom list/library template is based on
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("basetemplate",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string BaseTemplate
			{
				get
				{
					return baseTemplate;
				}
				set
				{
					baseTemplate=value;
				}
			}
			/// <summary>
			/// This is the relative path to the items.xml file
			/// </summary>
			private string relativeitemXML;
			/// <summary>
			/// This is the relative path to the items.xml file
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("relativeitemXML",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string RelativeitemXML
			{
				get
				{
					return relativeitemXML;
				}
				set
				{
					relativeitemXML=value;
				}
			}
        
			private bool quickLaunch;
			/// <summary>
			/// Boolean flag indicating whether the list/library will be added to the Quick Launch bar
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("quicklaunch",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public bool QuickLaunch
			{
				get
				{
					return quickLaunch;
				}
				set
				{
					quickLaunch=value;
				}
			}
        
			private bool webPart;
			/// <summary>
			/// Boolean flag indication whether a list webpart will be added to the default page
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("webpart",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public bool WebPart
			{
				get
				{
					return webPart;
				}
				set
				{
					webPart=value;
				}
			}

			private bool inheritPermissions=true;
			/// <summary>
			/// Boolean flag indication whether the permissions are inherited from the parent
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("inheritPermissions",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public bool InheritPermissions
			{
				get
				{
					return inheritPermissions;
				}
				set
				{
					inheritPermissions=value;
				}
			}
        
			private DataContainersCollection dataContainers;
			/// <summary>
			/// This is an array of child datacontainers (subfolders)
			/// </summary>
			/// <remarks>Valid only for document libraries</remarks>
			[System.Xml.Serialization.XmlElementAttribute("datacontainer", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public DataContainersCollection DataContainers
			{
				get	
				{
					return dataContainers;
				}
			}
        
			private AlertsCollection alerts;

			/// <summary>
			/// This is the list of list alerts created for this list/library
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("alerts", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public AlertsCollection Alerts
			{
				get
				{
					return alerts;
				}
			}

			/// <summary>
			/// This is the security node
			/// </summary>
			private Security security;
			/// <summary>
			/// This is the security information that will be applied to the site
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("security",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public Security Security
			{
				get
				{
					return security;
				}
			}
			private ViewsCollection views=null;
			/// <summary>
			/// This is the list of the views 
			/// </summary>
			[System.Xml.Serialization.XmlArrayAttribute("views",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			[System.Xml.Serialization.XmlArrayItemAttribute("view",Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=false)]
			public ViewsCollection Views
			{
				get
				{
					return views;
				}
			}

			/// <summary>
			/// Location of the default template for the library
			/// </summary>
			private string documenttemplateurl="";
			/// <summary>
			/// Location of the default template for the library
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("documenttemplateurl", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string DocumentTemplateUrl
			{
				get
				{
					return documenttemplateurl;
				}
				set
				{
					documenttemplateurl=value;
				}
			}
			private bool hidden=false;

			/// <summary>
			/// This indicates whether a list/library is hidden or not
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("hidden",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public bool Hidden
			{
				get
				{
					return hidden;
				}
				set
				{
					hidden=value;
				}
			}

			/// <summary>
			/// This is the default constructor for the DataContainer class
			/// </summary>
			/// <remarks>Instantiates the ChildDataContainer member</remarks>
			public DataContainer()
			{
				dataContainers=new DataContainersCollection();
				security = new Security();
				alerts = new AlertsCollection();
				Type=DataContainerType.Library;
				views=new ViewsCollection();
			}

			private Verbs operation=Verbs.create;
			/// <summary>
			/// This enum controls the site creation
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("operation",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public Verbs Operation
			{
				get
				{
					return operation;
				
				}
				set
				{
					operation=value;
				}
			}
			private string propertyBag;

			/// <summary>
			/// This will contain all the extra properties not included in the schema.xml
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("propertyBag",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string PropertyBag
			{
				get
				{
					return propertyBag;
				}
				set
				{
					propertyBag=value;
				}
			}


		}
		/// <summary>
		/// This is the class implementing the Users collection
		/// </summary>
		public class UsersCollection:ICollection
		{
			/// <summary>
			/// This is the default constructor for the Users class
			/// </summary>
			/// <remarks>Instantiates the users member</remarks>
			public UsersCollection()
			{
				users=new ArrayList();
			}
			private ArrayList users;
			#region ICollection Members

			/// <summary>
			/// Gets a value indicating whether access to the ArrayList is synchronized (thread-safe).
			/// </summary>
			/// <remarks>
			/// To guarantee the thread safety of the ArrayList, all operations must be done through the wrapper returned by the Synchronized method.
			/// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads.
			/// </remarks>
			public bool IsSynchronized
			{
				get
				{
				
					return users.IsSynchronized;
				}
			}

			/// <summary>
			/// Returns a value indicating the number of objects in the collection. Read-only.
			/// </summary>
			public int Count
			{
				get
				{
					return users.Count;
				}
			}
			/// <summary>
			/// Copies the entire User Array to a compatible one-dimensional Array, starting at the specified index of the target array.
			/// </summary>
			/// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
			/// <param name="index">The zero-based index in array at which copying begins</param>
			public void CopyTo(User[] a, int index)
			{
				users.CopyTo(a, index);
			}


			/// <summary>
			/// Copies the entire ArrayList to a compatible one-dimensional Array, starting at the specified index of the target array.
			/// </summary>
			/// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
			/// <param name="index">The zero-based index in array at which copying begins</param>
			public void CopyTo(Array a, int index)
			{
				users.CopyTo(a, index);
			}

			/// <summary>
			/// Gets an object that can be used to synchronize access to the ArrayList.
			/// </summary>
			/// <remarks>
			/// To create a synchronized version of the ArrayList, use the Synchronized method. However, derived classes can provide their own synchronized version of the ArrayList using the SyncRoot property. The synchronizing code must perform operations on the SyncRoot of the ArrayList, not directly on the ArrayList. This ensures proper operation of collections that are derived from other objects. 
			/// Specifically, it maintains proper synchronization with other threads that might be simultaneously modifying the ArrayList object.
			/// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or 
			/// catch the exceptions resulting from changes made by other threads.
			/// </remarks>
			public object SyncRoot
			{
				get
				{
					return users.SyncRoot;
				}
			}

			#endregion

			#region IEnumerable Members

			/// <summary>
			/// Returns an enumerator that can iterate through the ArrayList.
			/// </summary>
			/// <returns></returns>
			public IEnumerator GetEnumerator()
			{
				return users.GetEnumerator() ;
			}

			#endregion
			/// <summary>
			/// Gets the element at the specified index.
			/// </summary>
			public User this[int index]
			{
				get{return (User) users[index];}
			}
			/// <summary>
			/// Adds an object to the end of the ArrayList.
			/// </summary>
			/// <param name="newUser">New User to be added to the list</param>
			public void Add(User newUser)
			{
				users.Add(newUser);
			}
			/// <summary>
			/// This method removes a named item from the collection
			/// </summary>
			/// <param name="Name">This is the name of the User to be removed</param>
			public bool Remove(string Name)
			{
				int indexToRemove=-1;
				for(int i = 0 ; i<users.Count;i++)
				{
					User u=(User)users[i];
					if(0==u.Name.CompareTo(Name))
					{
						indexToRemove=i;
						break;
					}

				}
				if(indexToRemove>=0)
					users.RemoveAt(indexToRemove);
				return (indexToRemove>=0);
			}



		}
    
		/// <summary>
		/// This class represents the user/group that will be added to the SharePoint site.
		/// </summary>
		public class User 
		{
        
			private string role;
			/// <summary>
			/// This is the SharePoint role of the user
			/// </summary>
			/// <remarks>
			/// Usual values is one of these Reader, Contributor, Web Designer, Administrator
			/// </remarks>
			[System.Xml.Serialization.XmlElementAttribute("role",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string Role
			{
				get
				{
					return role;
				}
				set
				{
					role=value;

				}
			}

			private string account;
			/// <summary>
			/// This is the domain account name of the user
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("account",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string Account
			{
				get
				{
					return account;
				}
				set
				{
					account=value;

				}
			}    
			private string email;
			/// <summary>
			/// This is the email address of the user
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("email",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string Email
			{
				get
				{
					return email;
				}
				set
				{
					email=value;

				}
			}

        
			/// <summary>
			/// This is the name of the user
			/// </summary>
			private string name;
			/// <summary>
			/// This is the display name of the user
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("name",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string Name
			{
				get
				{
					return name;
				}
				set
				{
					name=value;

				}
			}
        
			/// <summary>
			/// This is the type of the user (Person/Group)
			/// </summary>
			private string type;
			/// <summary>
			/// This is the type of the user node
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("type",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string Type
			{
				get
				{
					return type;
				}
				set
				{
					type=value;

				}
			}

			/// <summary>
			/// This is the SPS permissions
			/// </summary>
			private string permissions;
			/// <summary>
			/// This is the SPS permissions
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("permissions",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string Permissions
			{
				get
				{
					return permissions;
				}
				set
				{
					permissions=value;

				}
			}

			/// <summary>
			/// This is the Xml export of an SPS user object
			/// </summary>
			private string xml;
			/// <summary>
			/// This is the Xml export of an SPS user object
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("xml",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string Xml
			{
				get
				{
					return xml;
				}
				set
				{
					xml=value;

				}
			}

		
		}
		/// <summary>
		/// This is the class implementing the Roles collection
		/// </summary>
		public class RolesCollection:ICollection
		{
			/// <summary>
			/// This is the default constructor for the Roles class
			/// </summary>
			/// <remarks>Instantiates the roles member</remarks>
			public RolesCollection()
			{
				roles=new ArrayList();
			}
			private ArrayList roles;
			#region ICollection Members

			/// <summary>
			/// Gets a value indicating whether access to the ArrayList is synchronized (thread-safe).
			/// </summary>
			/// <remarks>
			/// To guarantee the thread safety of the ArrayList, all operations must be done through the wrapper returned by the Synchronized method.
			/// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads.
			/// </remarks>
			public bool IsSynchronized
			{
				get
				{
				
					return roles.IsSynchronized;
				}
			}

			/// <summary>
			/// Returns a value indicating the number of objects in the collection. Read-only.
			/// </summary>
			public int Count
			{
				get
				{
					return roles.Count;
				}
			}

			/// <summary>
			/// Copies the entire Role Array to a compatible one-dimensional Array, starting at the specified index of the target array.
			/// </summary>
			/// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
			/// <param name="index">The zero-based index in array at which copying begins</param>
			public void CopyTo(Role[] a, int index)
			{
				roles.CopyTo(a, index);
			}

			/// <summary>
			/// Copies the entire ArrayList to a compatible one-dimensional Array, starting at the specified index of the target array.
			/// </summary>
			/// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
			/// <param name="index">The zero-based index in array at which copying begins</param>
			public void CopyTo(Array a, int index)
			{
				roles.CopyTo(a, index);
			}

			/// <summary>
			/// Gets an object that can be used to synchronize access to the ArrayList.
			/// </summary>
			/// <remarks>
			/// To create a synchronized version of the ArrayList, use the Synchronized method. However, derived classes can provide their own synchronized version of the ArrayList using the SyncRoot property. The synchronizing code must perform operations on the SyncRoot of the ArrayList, not directly on the ArrayList. This ensures proper operation of collections that are derived from other objects. 
			/// Specifically, it maintains proper synchronization with other threads that might be simultaneously modifying the ArrayList object.
			/// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or 
			/// catch the exceptions resulting from changes made by other threads.
			/// </remarks>
			public object SyncRoot
			{
				get
				{
					return roles.SyncRoot;
				}
			}

			#endregion

			#region IEnumerable Members

			/// <summary>
			/// Returns an enumerator that can iterate through the ArrayList.
			/// </summary>
			/// <returns></returns>
			public IEnumerator GetEnumerator()
			{
				return roles.GetEnumerator() ;
			}

			#endregion
			/// <summary>
			/// Gets the element at the specified index.
			/// </summary>
			public Role this[int index]
			{
				get{return (Role) roles[index];}
			}
			/// <summary>
			/// Adds an object to the end of the ArrayList.
			/// </summary>
			/// <param name="newRole">New Role to be added to the list</param>
			public void Add(Role newRole)
			{
				roles.Add(newRole);
			}

		}
    
		/// <summary>
		/// Class encapsulating an Role
		/// </summary>
		public class Role 
		{
        
			/// <summary>
			/// This is the role of the role
			/// </summary>
			private string roleName;
			/// <summary>
			/// This is the Role name
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("name",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string RoleName
			{
				get
				{
					return roleName;
				}
				set
				{
					roleName=value;
				}
			}
        
			/// <summary>
			/// This is the Permission of the role
			/// </summary>
			private string permissions;
			/// <summary>
			/// This is the Permission of the role
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("permissions",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string Permissions
			{
				get
				{
					return permissions;
				}
				set
				{
					permissions=value;
				}
			}
        
			/// <summary>
			/// This is the XML dump of the SPS role
			/// </summary>
			private string xml;
			/// <summary>
			/// This is the XML dump of the SPS role
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("xml",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string Xml
			{
				get
				{
					return xml;
				}
				set
				{
					xml=value;
				}
			}
        
		}

		/// <summary>
		/// This is the class implementing the Containers collection
		/// </summary>
		public class ContainersCollection:ICollection
		{
			/// <summary>
			/// This is the default constructor for the ContainersCollection class
			/// </summary>
			/// <remarks>Instantiates the containers member</remarks>
			public ContainersCollection()
			{
				containers=new ArrayList();
			}
			private ArrayList containers;
			#region ICollection Members

			/// <summary>
			/// Gets a value indicating whether access to the ArrayList is synchronized (thread-safe).
			/// </summary>
			/// <remarks>
			/// To guarantee the thread safety of the ArrayList, all operations must be done through the wrapper returned by the Synchronized method.
			/// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads.
			/// </remarks>
			public bool IsSynchronized
			{
				get
				{
				
					return containers.IsSynchronized;
				}
			}

			/// <summary>
			/// Returns a value indicating the number of objects in the collection. Read-only.
			/// </summary>
			public int Count
			{
				get
				{
					return containers.Count;
				}
			}

			/// <summary>
			/// Copies the entire Container Array to a compatible one-dimensional Array, starting at the specified index of the target array.
			/// </summary>
			/// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
			/// <param name="index">The zero-based index in array at which copying begins</param>
			public void CopyTo(Container[] a, int index)
			{
				containers.CopyTo(a, index);
			}

			/// <summary>
			/// Copies the entire ArrayList to a compatible one-dimensional Array, starting at the specified index of the target array.
			/// </summary>
			/// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
			/// <param name="index">The zero-based index in array at which copying begins</param>
			public void CopyTo(Array a, int index)
			{
				containers.CopyTo(a, index);
			}

			/// <summary>
			/// Gets an object that can be used to synchronize access to the ArrayList.
			/// </summary>
			/// <remarks>
			/// To create a synchronized version of the ArrayList, use the Synchronized method. However, derived classes can provide their own synchronized version of the ArrayList using the SyncRoot property. The synchronizing code must perform operations on the SyncRoot of the ArrayList, not directly on the ArrayList. This ensures proper operation of collections that are derived from other objects. 
			/// Specifically, it maintains proper synchronization with other threads that might be simultaneously modifying the ArrayList object.
			/// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or 
			/// catch the exceptions resulting from changes made by other threads.
			/// </remarks>
			public object SyncRoot
			{
				get
				{
					return containers.SyncRoot;
				}
			}

			#endregion

			#region IEnumerable Members

			/// <summary>
			/// Returns an enumerator that can iterate through the ArrayList.
			/// </summary>
			/// <returns></returns>
			public IEnumerator GetEnumerator()
			{
				return containers.GetEnumerator() ;
			}

			#endregion
			/// <summary>
			/// Gets the element at the specified index.
			/// </summary>
			public Container this[int index]
			{
				get{return (Container) containers[index];}
			}
			/// <summary>
			/// Adds an object to the end of the ArrayList.
			/// </summary>
			/// <param name="newContainer">New Container to be added to the list</param>
			public void Add(Container newContainer)
			{
				containers.Add(newContainer);
			}
			/// <summary>
			/// This method removes a named item from the collection
			/// </summary>
			/// <param name="Name">This is the name of the container to be removed</param>
			public bool Remove(string Name)
			{
				int indexToRemove=-1;
				for(int i = 0 ; i<containers.Count;i++)
				{
					Container c=(Container)containers[i];
					if(0==c.Name.CompareTo(Name))
					{
						indexToRemove=i;
						break;
					}

				}
				if(indexToRemove>=0)
					containers.RemoveAt(indexToRemove);
				return (indexToRemove>=0);
			}


		}
    
		/// <summary>
		/// This class representates the actual site/Area that will be created by the Importer
		/// </summary>
		/// <remarks><seealso cref="SharePoint.ImportExport.Core.Security"/><seealso cref="SharePoint.ImportExport.Core.DataContainer"/>
		/// </remarks>
		/// <example>
		/// <code>
		/// //This class is the actual site that will be created
		/// SharePoint.ImportExport.Core.Container container= new Container();
		/// rootContainer.Containers.Add(container);
		/// container.Name="Test";
		/// container.Owner="DOMAIN\\user";
		/// container.Contact="user@domain.com";
		/// container.Type="site";
		/// container.Template="STS#1";
		/// 
		/// //Add an contributor
		/// User user= new User();
		/// user.Account="DOMAIN\\User2";
		/// user.Role="contributor";
		/// user.Email="user2@domain.com";
		/// user.Name="Joe User";
		/// user.Type="Person";
		/// container.Security.Users.Add(user);
		/// </code></example>
		public class Container 
		{
			/// <summary>
			/// This is the default constructor for thr RootContainer class
			/// </summary>
			public Container()
			{
				containers=new ContainersCollection();
				dataContainers=new DataContainersCollection();
				security=new Security();
				design=new Design();

			}
			/// <summary>
			/// This is the site type that gets created ("site"=WSS,"area"=SPS) 
			/// </summary>
			private SiteType type=SiteType.Undefined;
			/// <summary>
			/// This is the type of the container
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("type",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public SiteType Type
			{
				get
				{

					return type;//(SiteType)Enum.Parse(typeof(SiteType), type,true);;
				}
				set
				{
					type=value;//.ToString();
				}
			}

			/// <summary>
			/// This is the name of the site/area that gets created
			/// </summary>
			private string name;
			/// <summary>
			/// This is the name of the site
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("name",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string Name
			{
				get
				{
					return name;
				}
				set
				{
					name=Miscallaneous.FixName(value);
				}
			}


			/// <summary>
			/// This is the description for the site/area
			/// </summary>
			private string description;
			/// <summary>
			/// This is the description of the container
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("description",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string Description
			{
				get
				{
					return description	;
				}
				set
				{
					description=value;
				}
			}


			/// <summary>
			/// This is the contact information for the site/area
			/// </summary>
			private string contact;
			/// <summary>
			/// This is the contact information of the site owner
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("contact",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string Contact
			{
				get
				{
					return contact;
				}
				set
				{
					contact=value;
				}
			}
			/// <summary>
			/// This is the owner information for the site/area
			/// </summary>
			private string owner;
			/// <summary>
			/// This is the Domain account information of the site owner
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("owner",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string Owner
			{
				get
				{
					return owner;
				}
				set
				{
					owner=value;
				}
			}

			/// <summary>
			/// This is the template that is used for the site/area
			/// </summary>
			/// <remarks>The template name corresponds to the directory name on the Web Front End Server. 
			/// STS#1 for an empty WSS site</remarks>
			private string template="";
			/// <summary>
			/// This is the template that the site/area is based on
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("template",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string Template
			{
				get
				{
					return template;
				}
				set
				{
					template=value;
				}
			}

			/// <summary>
			/// Boolean flag indicationg whether the site will be added to the site directory on the portal
			/// </summary>
			private bool showInSiteDirectory;
			/// <summary>
			/// This flag indicates whether the the site will be shown in the site directory
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("showinsitedirectory",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public bool ShowInSiteDirectory
			{
				get
				{
					return showInSiteDirectory;
				}
				set
				{
					showInSiteDirectory=value;
				}
			}
            private int timezoneID;
            /// <summary>
            /// This flag indicates whether the the site will be shown in the site directory
            /// </summary>
            [System.Xml.Serialization.XmlElementAttribute("timezoneID", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
            public int TimezoneID
            {
                get
                {
                    return timezoneID;
                }
                set
                {
                    timezoneID  = value;
                }
            }	
 
			/// <summary>
			/// Boolean flag indication whether the permissions are inherited from the parent
			/// </summary>
			private bool inheritPermissions=true;
			/// <summary>
			/// This flag indicates whether the container will inherit its permissions from its parent container
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("inheritPermissions",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public bool InheritPermissions
			{
				get
				{
					return inheritPermissions;
				}
				set
				{
					inheritPermissions=value;
				}
			}
			/// <summary>
			/// This is the security node
			/// </summary>
			private Security security;
			/// <summary>
			/// This is the security information that will be applied to the site
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("security",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public Security Security
			{
				get
				{
					return security;
				}
				set
				{
					security=value;
				}
			}
			/// <summary>
			/// This is a list of all the lists/libraries that will be created in the site/area
			/// </summary>
			private DataContainersCollection dataContainers;
			/// <summary>
			/// This is a list of all the lists/libraries that will be created in the site/area
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("datacontainer", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public DataContainersCollection DataContainers
			{
				get
				{
					return dataContainers;
				}
			}
			
        
			private ContainersCollection containers;
			/// <summary>
			/// This is a list of the subwebs/subareas that gets created in the site/area
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("container", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public ContainersCollection Containers
			{
				get
				{
					return containers;
				}
			}

			/// <summary>
			/// This wraps the design info for the site/area
			/// </summary>
			private Design design;
			/// <summary>
			/// This contains the design info (un-ghosted pages, web parts) of the site
			/// </summary>
			/// 
			[System.Xml.Serialization.XmlElementAttribute("design", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]

			public Design Design
			{
				get
				{
					return design;
				}
				set
				{
					design=value;
				}
			}

			/// <summary>
			/// This grabs the template for the site/area
			/// </summary>
			private string webtemplate;
			/// <summary>
			/// This contains the temaplte info for the site
			/// </summary>
			/// 
			[System.Xml.Serialization.XmlElementAttribute("webtemplate", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]

			public string WebTemplate
			{
				get
				{
					return webtemplate;
				}
				set
				{
					webtemplate=value;
				}
			}

			/// <summary>
			/// This grabs the configuration for the site/area
			/// </summary>
			private string configuration;
			/// <summary>
			/// This contains the configuration info for the site
			/// </summary>
			/// 
			[System.Xml.Serialization.XmlElementAttribute("configuration", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]

			public string Configuration
			{
				get
				{
					return configuration;
				}
				set
				{
					configuration=value;
				}
			}

			/// <summary>
			/// This grabs the Url for the site/area
			/// </summary>
			private string url;
			/// <summary>
			/// This contains the Url info for the site
			/// </summary>
			/// 
			[System.Xml.Serialization.XmlElementAttribute("url", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]

			public string Url
			{
				get
				{
					return url;
				}
				set
				{
					url=value;
				}
			}

			private int lcid=System.Threading.Thread.CurrentThread.CurrentUICulture.LCID;

			/// <summary>
			/// This is the locale of the site
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("lcid", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public int Locale
			{
				get
				{
					return lcid;
				}
				set
				{
					lcid=value;
				}
			}
			private int sitelcid=System.Threading.Thread.CurrentThread.CurrentUICulture.LCID;

			/// <summary>
			/// This is the locale of the site
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("sitelcid", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public int SiteLocale
			{
				get
				{
					return sitelcid;
				}
				set
				{
					sitelcid=value;
				}
			}

			private Verbs operation=Verbs.create;
			/// <summary>
			/// This enum controls the site creation
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("operation",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public Verbs Operation
			{
				get
				{
					return operation;
				
				}
				set
				{
					operation=value;
				}
			}

			private string propertyBag;

			/// <summary>
			/// This will contain all the extra properties not included in the schema.xml
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("propertyBag",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]

			public string PropertyBag
			{
				get
				{
					return propertyBag;
				}
				set
				{
					propertyBag=value;
				}
			}
		}
		/// <summary>
		/// This is the class encapsulating the user information
		/// </summary>
		/// <example>
		/// <code>
		/// //Add an contributor
		/// User user= new User();
		/// user.Account="DOMAIN\\User2";
		/// user.Role="contributor";
		/// user.Email="user2@domain.com";
		/// user.Name="Joe User";
		/// user.Type="Person";
		/// container.Security.User.Add(user);
		/// </code></example>
		public class Security
		{
			private UsersCollection users;
			/// <summary>
			/// This is a list of all the users
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("user",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public UsersCollection Users
			{
				get
				{
					return users;
				}
			}
			private RolesCollection roles;
			/// <summary>
			/// This is a list of all sitegroups that the Importer will create
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("role",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public RolesCollection Roles
			{
				get
				{
					return roles;
				}
			}
			/// <summary>
			/// This is the default constructor for the Security class
			/// </summary>
			/// <remarks>Instantiates the User member</remarks>
			public Security()
			{
				users = new UsersCollection();
				roles = new RolesCollection();
		
			}
		}
    
		/// <summary>
		/// This is the class implementing the RootsContainer collection
		/// </summary>
		public class RootContainersCollection:ICollection
		{
			/// <summary>
			/// This is the default constructor for the RootContainersCollection class
			/// </summary>
			/// <remarks>Instantiates the rootContainers member</remarks>
			public RootContainersCollection()
			{
				rootContainers=new ArrayList();
			}
			private ArrayList rootContainers;
			#region ICollection Members

			/// <summary>
			/// Gets a value indicating whether access to the ArrayList is synchronized (thread-safe).
			/// </summary>
			/// <remarks>
			/// To guarantee the thread safety of the ArrayList, all operations must be done through the wrapper returned by the Synchronized method.
			/// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads.
			/// </remarks>
			public bool IsSynchronized
			{
				get
				{
				
					return rootContainers.IsSynchronized;
				}
			}

			/// <summary>
			/// Returns a value indicating the number of objects in the collection. Read-only.
			/// </summary>
			public int Count
			{
				get
				{
					return rootContainers.Count;
				}
			}
			/// <summary>
			/// Copies the entire RootContainer Array to a compatible one-dimensional Array, starting at the specified index of the target array.
			/// </summary>
			/// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
			/// <param name="index">The zero-based index in array at which copying begins</param>
			public void CopyTo(RootContainer[] a, int index)
			{
				rootContainers.CopyTo(a, index);
			}


			/// <summary>
			/// Copies the entire ArrayList to a compatible one-dimensional Array, starting at the specified index of the target array.
			/// </summary>
			/// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
			/// <param name="index">The zero-based index in array at which copying begins</param>
			public void CopyTo(Array a, int index)
			{
				rootContainers.CopyTo(a, index);
			}

			/// <summary>
			/// Gets an object that can be used to synchronize access to the ArrayList.
			/// </summary>
			/// <remarks>
			/// To create a synchronized version of the ArrayList, use the Synchronized method. However, derived classes can provide their own synchronized version of the ArrayList using the SyncRoot property. The synchronizing code must perform operations on the SyncRoot of the ArrayList, not directly on the ArrayList. This ensures proper operation of collections that are derived from other objects. 
			/// Specifically, it maintains proper synchronization with other threads that might be simultaneously modifying the ArrayList object.
			/// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or 
			/// catch the exceptions resulting from changes made by other threads.
			/// </remarks>
			public object SyncRoot
			{
				get
				{
					return rootContainers.SyncRoot;
				}
			}

			#endregion

			#region IEnumerable Members

			/// <summary>
			/// Returns an enumerator that can iterate through the ArrayList.
			/// </summary>
			/// <returns></returns>
			public IEnumerator GetEnumerator()
			{
				return rootContainers.GetEnumerator() ;
			}

			#endregion
			/// <summary>
			/// Gets the element at the specified index.
			/// </summary>
			public RootContainer this[int index]
			{
				get{return (RootContainer) rootContainers[index];}
			}
			/// <summary>
			/// Adds an object to the end of the ArrayList.
			/// </summary>
			/// <param name="newRootContainer">New RootContainer to be added to the list</param>
			public void Add(RootContainer newRootContainer)
			{
				rootContainers.Add(newRootContainer);
			}

		}

		/// <summary>
		/// This is the encapsulation of the rootcontainer
		/// </summary>
		/// <remarks><seealso cref="SharePoint.ImportExport.Core.Container"/><seealso cref="SharePoint.ImportExport.Core.Settings"/></remarks>
		public class RootContainer
		{
        
			private SiteType  type=SiteType.Undefined;
			/// <summary>
			/// This is the starting point of the import. 
			/// </summary>
			/// <remarks>Valid choices are SiteType.Site for WSS and SiteType.Area for SPS</remarks>
			[System.Xml.Serialization.XmlElementAttribute("type",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public SiteType Type
			{
				get
				{

					return type;
				}
				set
				{
					type=value;
				}
			}

        
			private string name;
			/// <summary>
			/// This is the name of the container in whice the sites/areas will be created
			/// </summary>
			/// <remarks>Usually Sites for WSS sites or Topics for Portal areas</remarks>
			[System.Xml.Serialization.XmlElementAttribute("name",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string Name
			{
				get
				{
					return name;
				}
				set
				{
					name=value;
				}
			}
			
        
			private ContainersCollection containers;
			/// <summary>
			/// This is a list of all the sites/areas that will be created
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("container",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public ContainersCollection Containers
			{
				get
				{
					return containers;
				}

			}
			/// <summary>
			/// This is the default constructor for the RootContainer class
			/// </summary>
			public RootContainer()
			{
				containers=new ContainersCollection();
			}
			/// <summary>
			/// Constructor
			/// </summary>
			/// <param name="type">SiteType</param>
			/// <param name="name">Name of Site/Area</param>
			public RootContainer(SiteType type, string name)
			{
				this.Type=type;
				this.Name=name;

				containers=new ContainersCollection();
			}
		}

	}
